package com.cz.ssyx.search.service.impl;

import com.cz.ssyx.client.activity.ActivityFeignClient;
import com.cz.ssyx.client.product.ProductFeignClient;
import com.cz.ssyx.common.auth.AuthContextHolder;
import com.cz.ssyx.enums.SkuType;
import com.cz.ssyx.model.product.Category;
import com.cz.ssyx.model.product.SkuInfo;
import com.cz.ssyx.model.search.SkuEs;
import com.cz.ssyx.search.repository.SkuRepository;
import com.cz.ssyx.search.service.SkuService;
import com.cz.ssyx.vo.search.SkuEsQueryVo;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @descriptions:
 * @author: Joker.
 * @date: 2024/4/19 20:42
 * @version: 1.0
 */

@Service
public class SkuServiceImpl implements SkuService {

    @Resource
    private RestHighLevelClient client;

    //es数据流接口
    @Autowired
    private SkuRepository skuRepository;

    //远程调用商品的接口
    @Autowired
    private ProductFeignClient productFeignClient;

    //远程调用活动规则的接口
    @Autowired
    private ActivityFeignClient activityFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    //更新商品热度
    @Override
    public void incrHotScore(Long skuId) {
        String key = "hotScore";
        //redis保存数据，每次＋1
        Double hotScore = redisTemplate.opsForZSet().incrementScore(key, "skuId: " + skuId, 1);

        //规则，即热度加十次，再刷新es
        if (hotScore %10 == 0) {
            Optional<SkuEs> optional = skuRepository.findById(skuId);
            SkuEs skuEs = optional.get();
            skuEs.setHotScore(Math.round(hotScore));
            skuRepository.save(skuEs);
        }
    }

    @Override
    public List<String> autocompleteSkuName(String prefix) {
        List<String> result = new ArrayList<>();
        CompletionSuggestionBuilder suggestionBuilder = SuggestBuilders.completionSuggestion("suggest").prefix(prefix).size(10);
        SuggestBuilder suggestBuilder = new SuggestBuilder().addSuggestion("sku-name-suggest", suggestionBuilder);
        SearchRequest request = new SearchRequest("skues");
        request.source().suggest(suggestBuilder);
        try {
            SearchResponse search = client.search(request, RequestOptions.DEFAULT);
            Suggest suggest = search.getSuggest();
            CompletionSuggestion  suggestion = suggest.getSuggestion("sku-name-suggest");
            for (CompletionSuggestion.Entry entry : suggestion.getEntries()) {
                for (CompletionSuggestion.Entry.Option option : entry) {
                    result.add(option.getText().string());
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    //上架
    @Override
    public void upperSku(Long skuId) {

        //通过远程调用，根据skuId获取商品信息
        SkuInfo skuInfo = productFeignClient.getSkuInfoById(skuId);
        if (skuInfo == null) {
            return;
        }

        //获取分类信息
        Category category = productFeignClient.getCategoryById(skuInfo.getCategoryId());

        //封装分类信息
        SkuEs skuEs = new SkuEs();
        skuEs.setCategoryId(category.getId());
        skuEs.setCategoryName(category.getName());

        //封装商品基本信息
        skuEs.setId(skuInfo.getId());
        skuEs.setKeyword(skuInfo.getSkuName()+","+skuEs.getCategoryName());
        skuEs.setWareId(skuInfo.getWareId());
        skuEs.setIsNewPerson(skuInfo.getIsNewPerson());
        skuEs.setImgUrl(skuInfo.getImgUrl());
        skuEs.setTitle(skuInfo.getSkuName());
        if(skuInfo.getSkuType() == SkuType.COMMON.getCode()) {
            skuEs.setSkuType(0);
            skuEs.setPrice(skuInfo.getPrice().doubleValue());
            skuEs.setStock(skuInfo.getStock());
            skuEs.setSale(skuInfo.getSale());
            skuEs.setPerLimit(skuInfo.getPerLimit());
        }

        //调用方法添加ES
        skuRepository.save(skuEs);
    }

    //下架
    @Override
    public void lowerSku(Long skuId) {
        skuRepository.deleteById(skuId);
    }

    //删除商品
    @Override
    public void deleteSku(Long skuId) {
        skuRepository.deleteById(skuId);
    }

    //获取爆款商品
    @Override
    public List<SkuEs> findHotSkuList() {
        Pageable pageable = PageRequest.of(0, 10);
        return skuRepository.findByOrderByHotScoreDesc(pageable).getContent();
    }

    @Override
    public Page<SkuEs> search(Pageable pageable, SkuEsQueryVo skuEsQueryVo) {
        //1.向skuEsQueryVo设置wareId，可以从当前登录用户中获取wareId
        skuEsQueryVo.setWareId(AuthContextHolder.getWareId());

        //2.使用skuRepository里的方法进行条件查询
        Page<SkuEs> pageModel = null;
        String keyword = skuEsQueryVo.getKeyword();
        if (StringUtils.isEmpty(keyword)) {
            //keyword为空，根据CategoryId + WareId查询
            pageModel = skuRepository
                                .findByCategoryIdAndWareId(skuEsQueryVo.getCategoryId(),
                                                            skuEsQueryVo.getWareId(),pageable);
        } else {
            //keyword不为空，根据keyword + WareId查询
            pageModel = skuRepository.findByKeywordAndWareId(skuEsQueryVo.getKeyword(), skuEsQueryVo.getWareId(), pageable);
        }

        //3.查询商品参加的优惠活动
        //先从分页中获取商品列表
        List<SkuEs> skuEsList = pageModel.getContent();
        if (!CollectionUtils.isEmpty(skuEsList)) {
            //如果商品列表不为空，遍历出商品id
            List<Long> skuEsIdList = skuEsList.stream().map(SkuEs::getId).collect(Collectors.toList());

            //远程调用获取商品参加的活动
            Map<Long, List<String>> skuIdRuleListMap =
                    activityFeignClient.findActivity(skuEsIdList);

            //将活动数据封装到skuEs的ruleList中
            if (skuIdRuleListMap != null){
                skuEsList.forEach(item ->{
                    item.setRuleList(skuIdRuleListMap.get(item.getId()));
                });
            }
        }


        return pageModel;
    }


}
